package cn.wolfcode.business.service.impl;

import java.io.InputStream;
import java.security.Security;
import java.text.SimpleDateFormat;
import java.util.*;

import cn.wolfcode.business.domain.BpmnInfo;
import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.domain.BusServiceItem;
import cn.wolfcode.business.mapper.BpmnInfoMapper;
import cn.wolfcode.business.mapper.BusServiceItemMapper;
import cn.wolfcode.business.vo.HistoryVO;
import cn.wolfcode.business.vo.PackageAuditVO;
import cn.wolfcode.common.exception.ServiceException;
import cn.wolfcode.common.utils.DateUtils;
import cn.wolfcode.common.utils.PageUtils;
import cn.wolfcode.common.utils.SecurityUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.ServiceImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.CarPackageAuditMapper;
import cn.wolfcode.business.domain.CarPackageAudit;
import cn.wolfcode.business.service.ICarPackageAuditService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 套餐审核信息Service业务层处理
 * 
 * @author dalang
 * @date 2023-11-03
 */
@Service
@Transactional
public class CarPackageAuditServiceImpl implements ICarPackageAuditService 
{
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;

    @Autowired BpmnInfoMapper bpmnInfoMapper;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private BusServiceItemMapper serviceItemMapper;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;

    /**
     * 查询套餐审核信息
     * 
     * @param id 套餐审核信息主键
     * @return 套餐审核信息
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询套餐审核信息列表
     * 
     * @param carPackageAudit 套餐审核信息
     * @return 套餐审核信息
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
    }

    /**
     * 新增套餐审核信息
     * 
     * @param carPackageAudit 套餐审核信息
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改套餐审核信息
     * 
     * @param carPackageAudit 套餐审核信息
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 批量删除套餐审核信息
     * 
     * @param ids 需要删除的套餐审核信息主键
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(Long[] ids)
    {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(ids);
    }

    /**
     * 删除套餐审核信息信息
     * 
     * @param id 套餐审核信息主键
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }

    @Override
    public InputStream getProcessImg(Long id) {
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectLastByType(CarPackageAudit.FLOW_AUDIT_TYPE);
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(bpmnInfo.getVersion())
                .singleResult();

        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(id);

        List<String> activeActivityIds = new ArrayList<>();
        if(audit.getStatus().equals(CarPackageAudit.STATUS_IN_ROGRESS)){
            activeActivityIds = runtimeService.getActiveActivityIds(audit.getInstanceId());
        }else{
            activeActivityIds = Collections.emptyList();
        }

        DefaultProcessDiagramGenerator processDiagramGenerator = new DefaultProcessDiagramGenerator();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
        /**
         * 第一个参数: 流程定义模型
         * 第二个参数: 高亮节点集合
         * 第三个参数: 高亮连线集合
         */
        InputStream inputStream = processDiagramGenerator.generateDiagram(bpmnModel,
                activeActivityIds,
                Collections.emptyList(),
                "宋体",
                "宋体",
                "宋体");

        return inputStream;
    }

    @Override
    public void auditCancel(Long id) {
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(id);
        if (audit==null) {
            throw new ServiceException("参数异常");
        }
        if (!CarPackageAudit.STATUS_IN_ROGRESS.equals(audit.getStatus())) {
            throw new ServiceException("审核中状态才允许撤销");
        }
        serviceItemMapper
                .updateServiceItemStatus(audit.getServiceItemId(), BusServiceItem.AUDITSTATUS_INIT);

        audit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAuditMapper.updateCarPackageAudit(audit);

        runtimeService.deleteProcessInstance(audit.getInstanceId(),"审核已被撤销");
    }

    @Override
    public List<HistoryVO> queryHistory(Long instanceId) {
        if (instanceId==null) {
            throw new ServiceException("参数异常");
        }
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectLastByType(CarPackageAudit.FLOW_AUDIT_TYPE);

        List<HistoricTaskInstance> list = historyService
                .createHistoricTaskInstanceQuery()
                .processInstanceId(instanceId.toString())
//                .processDefinitionKey(bpmnInfo.getProcessDefinitionKey())
                .finished()
                .list();

        ArrayList<HistoryVO> vos = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (HistoricTaskInstance task : list) {
            HistoryVO vo = new HistoryVO();
            vo.setTaskName(task.getName());
            vo.setEndTime(sdf.format(task.getEndTime()));
            vo.setStartTime(sdf.format(task.getStartTime()));

            vo.setDurationInMillis(task.getDurationInMillis() / 1000 + "s");

            List<Comment> comments = taskService.getTaskComments(task.getId());
            if (comments != null || comments.size() > 0) {
                StringBuilder sb = new StringBuilder(80);
                for (Comment comment : comments) {
                    sb.append(comment.getFullMessage());
                }
                vo.setComment(sb.toString());
            }
            vos.add(vo);
        }

        return vos;
    }

    @Override
    public List<CarPackageAudit> todoQuery(CarPackageAudit carPackageAudit) {
//        List<Task> list = taskService.createTaskQuery()
//                .taskAssignee(SecurityUtils.getUserId().toString()).list();
//        if (list == null || list.size() == 0) {
//            return null;
//        }
//        List<String> ids = new ArrayList<>();
//        for (Task task : list) {
//            ids.add(task.getProcessInstanceId());
//        }
//        PageUtils.startPage();
//
//        return carPackageAuditMapper.selectByInstanceIds(ids);

        PageUtils.startPage();

//        List<CarPackageAudit> list = carPackageAuditMapper.selectByUserId(SecurityUtils.getUserId(),carPackageAudit.getParams(),carPackageAudit.getStatus());
        List<CarPackageAudit> list = carPackageAuditMapper.selectHisByUserId(SecurityUtils.getUserId(),carPackageAudit,"act_ru_task");

        return list;
    }

    @Override
    public void auditSubmit(PackageAuditVO vo) {
        if (vo==null) {
            throw new ServiceException("参数异常");
        }
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(vo.getId());
        if (audit==null|| !CarPackageAudit.STATUS_IN_ROGRESS.equals(audit.getStatus())) {
            throw new ServiceException("参数异常或状态异常");
        }
        Task task = taskService.createTaskQuery()
                .processInstanceId(audit.getInstanceId())
                .singleResult();

        if (task==null) {
            throw new ServiceException("该流程已被审核，请刷新页面");
        }

        String message = "";
        boolean flag = CarPackageAudit.STATUS_PASS.equals(vo.getAuditStatus());
        if (flag) {
            //通过
            message = "审批人:" + SecurityUtils.getUsername() + "通过, 审核备注:[" + vo.getAuditInfo() + "]";
        }else{
            //拒绝
            message = "审批人:" + SecurityUtils.getUsername() + "拒绝, 审核备注:[" + vo.getAuditInfo() + "]";
        }
        taskService.addComment(task.getId(),audit.getInstanceId().toString(),message);
        HashMap<String, Object> map = new HashMap<>();

        map.put("shopOwner",flag);
        taskService.complete(task.getId(),map);

        if(flag){
            // 审核通过
            Task nextTask = taskService.createTaskQuery().processInstanceId(audit.getInstanceId()).singleResult();
            if (nextTask==null) {
                serviceItemMapper.updateServiceItemStatus(audit.getServiceItemId(),BusServiceItem.AUDITSTATUS_APPROVED);
                audit.setStatus(CarPackageAudit.STATUS_PASS);
                carPackageAuditMapper.updateCarPackageAudit(audit);
            }
            // 审核通过且接下来还有节点，则什么都不做
        }else{
            serviceItemMapper.updateServiceItemStatus(audit.getServiceItemId(),BusServiceItem.AUDITSTATUS_REPLY);
            audit.setStatus(CarPackageAudit.STATUS_REJECT);
            carPackageAuditMapper.updateCarPackageAudit(audit);
        }

    }

    @Override
    public List<CarPackageAudit> doneQuery(CarPackageAudit carPackageAudit) {
        if (carPackageAudit==null) {
            throw new ServiceException("参数异常");
        }
//
//        List<HistoricTaskInstance> list = historyService
//                .createHistoricTaskInstanceQuery()
//                .taskAssignee(SecurityUtils.getUserId()
//                .toString()).list();
//
//        if (list==null||list.size()<1) {
//            return null;
//        }
//
//        List<String> ids = new ArrayList<>();
//
//        for (HistoricTaskInstance historicTaskInstance : list) {
//            ids.add(historicTaskInstance.getProcessInstanceId());
//        }
//        PageUtils.startPage();
//        return carPackageAuditMapper.selectByInstanceIds(ids);


        PageUtils.startPage();

//        List<CarPackageAudit> list = carPackageAuditMapper.selectHisByUserId(SecurityUtils.getUserId(),carPackageAudit.getParams(),carPackageAudit.getStatus());
        List<CarPackageAudit> list = carPackageAuditMapper.selectHisByUserId(SecurityUtils.getUserId(),carPackageAudit,"act_hi_taskinst");

        return list;
    }
}
